import {marked} from 'marked';
import hljs from 'highlight.js';
import 'highlight.js/styles/github.css';

/**
 * 代码高亮处理，带大小限制
 * @param {string} code - 代码内容
 * @param {string} language - 语言
 * @returns {string} - 高亮后的HTML
 */
const highlightWithLimit = (code, language) => {
    try {
        // 确保code是字符串类型
        if (code === null || code === undefined || typeof code !== 'string') {
            code = String(code || '');
        }

        // 设置大小限制为10KB，超过则不进行高亮处理
        const MAX_SIZE = 10 * 1024;

        if (code.length > MAX_SIZE) {
            // 对超长代码进行HTML转义但不高亮
            return code
                .replace(/&/g, '&amp;')
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/"/g, '&quot;')
                .replace(/'/g, '&#039;');
        }

        // 确保language是字符串
        const validLanguage = (typeof language === 'string' && hljs.getLanguage(language)) ? language : 'plaintext';
        return hljs.highlight(code, {language: validLanguage}).value;
    } catch (err) {
        // 确保返回安全的HTML字符串
        if (typeof code === 'string') {
            return code
                .replace(/&/g, '&amp;')
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/"/g, '&quot;')
                .replace(/'/g, '&#039;');
        } else {
            return '';
        }
    }
};

/**
 * 初始化Markdown解析器配置
 */
marked.setOptions({
    renderer: new marked.Renderer(),
    highlight: highlightWithLimit,
    langPrefix: 'hljs language-',
    pedantic: false,
    gfm: true, // 启用GitHub风格Markdown
    breaks: true, // 启用换行符转换为<br>
    sanitize: false, // 不转义HTML
    smartypants: false,
    headerIds: false, // 禁用header IDs，避免冲突
    mangle: false, // 禁用转义标点符号
    silent: false // 显示错误
});

// 自定义渲染器，添加对特殊内容的支持
const customRenderer = new marked.Renderer();

// 安全地将任何类型转换为字符串
const safeToString = (value) => {
    if (value === null || value === undefined) {
        return '';
    }

    if (typeof value === 'string') {
        // 处理字符串中的[object Object]undefined问题
        return value.replace(/\[object Object]undefined/g, '')
            .replace(/\[object Object]/g, '{}')
            .replace(/undefined/g, '');
    }

    if (typeof value === 'object') {
        try {
            // 处理undefined值
            const cleanObj = JSON.parse(JSON.stringify(value, (key, val) => {
                return val === undefined ? null : val;
            }));
            // 尝试将对象转为JSON字符串
            return JSON.stringify(cleanObj, null, 2);
        } catch (e) {
            return String(value).replace(/\[object Object]/g, '{}').replace(/undefined/g, '');
        }
    }

    return String(value);
};

// 安全地处理标记语言
const safeMarked = (content) => {
    try {
        return marked(safeToString(content));
    } catch (err) {
        return safeToString(content)
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/\n/g, '<br>');
    }
};

/**
 * 直接处理HTML内容中的[object Object]undefined问题
 * @param {string} html - 原始HTML内容
 * @returns {string} - 处理后的HTML
 */
const cleanHtmlObjectText = (html) => {
    if (!html || typeof html !== 'string') return html;

    return html.replace(/\[object Object]undefined/g, '')
        .replace(/\[object Object]/g, '{}')
        .replace(/undefined/g, '');
};

// 增强代码块渲染
customRenderer.code = function (code, language) {
    // 确保code是字符串类型
    if (code === null || code === undefined || typeof code !== 'string') {
        // 如果是对象，尝试序列化为JSON字符串
        if (typeof code === 'object') {
            try {
                // 检查是否为代码对象
                if (code.type === 'code' && (code.text || code.raw)) {
                    const codeContent = code.text || code.raw || '';
                    const langTag = code.lang || 'plaintext';
                    // 直接返回代码内容
                    code = codeContent;
                    language = langTag;
                } else {
                    code = JSON.stringify(code, null, 2);
                    // 如果是JSON，将语言设为json
                    if (language !== 'json' && !language) {
                        language = 'json';
                    }
                }
            } catch (e) {
                code = String(code || '');
            }
        } else {
            code = String(code || '');
        }
    }

    // 尝试识别和提取JSON中的代码对象
    if (language === 'json' && typeof code === 'string') {
        try {
            const jsonObj = JSON.parse(code);
            if (jsonObj && jsonObj.type === 'code' && (jsonObj.text || jsonObj.raw)) {
                // 提取代码内容和语言
                code = jsonObj.text || jsonObj.raw || '';
                language = jsonObj.lang || 'plaintext';
            }
        } catch (e) {
            // 解析失败，保持原样
        }
    }

    // 确保language是字符串
    const validLanguage = (typeof language === 'string' && hljs.getLanguage(language)) ? language : 'plaintext';

    // 使用同一个高亮函数处理
    const highlightedCode = highlightWithLimit(code, validLanguage);

    // 检查代码大小，对大型代码块添加折叠功能
    const isLargeCodeBlock = code.length > 3000;

    try {
        // 安全地编码代码内容
        const encodedCode = encodeURIComponent(code);

        let codeBlockHeader = `
      <div class="code-header">
        <span class="code-language">${validLanguage}</span>
        <button class="copy-button" data-code="${encodedCode}">复制</button>
      </div>
    `;

        if (isLargeCodeBlock) {
            codeBlockHeader = `
        <div class="code-header">
          <span class="code-language">${validLanguage}</span>
          <span class="code-size">${Math.round(code.length / 1024 * 10) / 10}KB</span>
          <button class="copy-button" data-code="${encodedCode}">复制</button>
        </div>
      `;
        }

        return `<div class="code-block-container ${isLargeCodeBlock ? 'large-code-block' : ''}">
      ${codeBlockHeader}
      <pre class="hljs"><code class="${validLanguage}">${highlightedCode}</code></pre>
    </div>`;
    } catch (err) {
        // 提供简单的备用渲染
        return `<pre><code>${
            code.replace(/&/g, '&amp;')
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
        }</code></pre>`;
    }
};

// 设置渲染器
marked.setOptions({renderer: customRenderer});

// 预处理阶段保存原始表格文本
const markdownTables = [];

// 在预处理时保存表格
const saveTablesBeforeProcessing = (text) => {
    if (!text || typeof text !== 'string') return text;

    // 查找表格文本并替换为占位符
    let processedText = text;
    const lines = text.split('\n');
    let tableStart = -1;
    let tableLines = [];

    for (let i = 0; i < lines.length; i++) {
        if (lines[i].includes('|')) {
            // 可能是表格的开始
            if (tableStart === -1) {
                tableStart = i;
                tableLines = [lines[i]];
            } else {
                tableLines.push(lines[i]);
            }
        } else if (tableStart !== -1 && lines[i].trim() === '') {
            // 表格结束
            if (tableLines.length >= 2) {
                extracted();
            }

            tableStart = -1;
            tableLines = [];
        }
    }

    function extracted() {
        const tableText = tableLines.join('\n');
        const placeholder = `<!--TABLE_PLACEHOLDER_${markdownTables.length}-->`;
        markdownTables.push(tableText);

        // 替换原文中的表格文本为占位符
        const startIndex = processedText.indexOf(tableLines[0]);
        const endIndex = startIndex + tableText.length;
        processedText = processedText.substring(0, startIndex) +
            placeholder +
            processedText.substring(endIndex);
    }

    // 处理文件尾部可能的表格
    if (tableStart !== -1 && tableLines.length >= 2) {
        extracted();
    }

    return processedText;
};

// 还原表格占位符
const restoreTablesAfterProcessing = (html) => {
    if (!html || typeof html !== 'string') return html;

    // 查找占位符并替换回表格
    let processedHtml = html;
    for (let i = 0; i < markdownTables.length; i++) {
        const placeholder = `<!--TABLE_PLACEHOLDER_${i}-->`;
        if (processedHtml.includes(placeholder)) {
            // 生成表格HTML
            const tableText = markdownTables[i];
            const tableHtml = generateTableHtmlFromText(tableText);
            processedHtml = processedHtml.replace(placeholder, tableHtml || tableText);
        }
    }

    return processedHtml;
};

/**
 * 从表格文本生成HTML表格
 */
const generateTableHtmlFromText = (text) => {
    try {
        if (!text || !text.includes('|')) return null;

        const lines = text.split('\n').filter(line => line.trim());
        if (lines.length < 2) return null;

        // 规范化行
        const normalizedLines = lines.map(line => {
            let normalized = line.trim();
            if (!normalized.startsWith('|')) normalized = '|' + normalized;
            if (!normalized.endsWith('|')) normalized = normalized + '|';
            return normalized;
        });

        // 获取表头
        const headerCells = normalizedLines[0].split('|')
            .map(cell => cell.trim())
            .filter(cell => cell);

        // 检查分隔行
        let dataStartRow = 1;
        let hasSeparator = false;

        if (normalizedLines.length > 1 && normalizedLines[1].includes('-')) {
            hasSeparator = true;
            dataStartRow = 2;
        }

        if (!hasSeparator) {
            return null; // 要求有分隔行才能正确识别为表格
        }

        // 构建表格HTML
        let html = '<div class="table-container"><table class="formatted-table">';

        // 表头
        html += '<thead><tr>';
        for (const cell of headerCells) {
            html += `<th>${cell}</th>`;
        }
        html += '</tr></thead><tbody>';

        // 表格内容
        for (let i = dataStartRow; i < normalizedLines.length; i++) {
            const rowCells = normalizedLines[i].split('|')
                .map(cell => cell.trim())
                .filter(cell => cell);

            html += '<tr>';
            for (const cell of rowCells) {
                html += `<td>${cell}</td>`;
            }
            html += '</tr>';
        }

        html += '</tbody></table></div>';
        return html;
    } catch (e) {
        return null;
    }
};

/**
 * 预处理文本，处理常见的格式问题
 * @param {string} text - 原始文本
 * @returns {string} - 预处理后的文本
 */
const preProcessText = (text) => {
    // 确保输入是字符串
    if (typeof text !== 'string') {
        text = String(text || '');
    }

    try {
        // 去除文本两端的空白
        text = text.trim();

        // 清空表格列表
        markdownTables.length = 0;

        // 保存表格文本
        text = saveTablesBeforeProcessing(text);

        // 检测是否已经是完整的代码块格式
        if (text.startsWith('```') && text.endsWith('```')) {
            return text;
        }

        // 处理特殊情况：如果文本以三个反引号开始但不以三个反引号结束，添加结束标记
        if (text.startsWith('```') && !text.endsWith('```')) {
            text = text + '\n```';
        }

        return text
            // 确保代码块正确格式化
            .replace(/```(\w*)\n/g, '```$1\n')
            // 处理可能的LaTeX公式
            .replace(/\$\$(.*?)\$\$/g, '<div class="math-block">$$$1$$</div>')
            .replace(/\$([^$]+)\$/g, '<span class="math-inline">$$$1$$</span>')
            // 优化列表格式
            .replace(/^\s*[-*+]\s/gm, '- ')
            .replace(/^\s*(\d+)\.\s/gm, '$1. ');
    } catch (err) {
        return text; // 出错时返回原始文本
    }
};

/**
 * 后处理HTML，增强一些特殊功能
 * @param {string} html - 原始HTML
 * @returns {string} - 处理后的HTML
 */
const postProcessHtml = (html) => {
    // 确保输入是字符串
    if (typeof html !== 'string') {
        html = String(html || '');
    }

    try {
        // 先清理[object Object]undefined问题
        html = cleanHtmlObjectText(html);

        return html
            // 添加目标="_blank"到外部链接
            .replace(/<a\s+href="(https?:\/\/[^"]+)"/g, '<a href="$1" target="_blank" rel="noopener noreferrer"')
            // 处理复制按钮功能 - 不再使用内联onclick事件
            .replace(/class="copy-button"/g, 'class="copy-button"')
            // 确保表格内单元格不会过宽
            .replace(/<td([^>]*)>(.*?)<\/td>/g, (match, attrs, content) => {
                // 再次清理单元格内容中的[object Object]undefined
                content = content.replace(/\[object Object]undefined/g, '')
                    .replace(/\[object Object]/g, '{}')
                    .replace(/undefined/g, '');

                // 如果内容是纯文本且没有空格，添加word-break
                if (content && content.length > 30 && !content.includes(' ') && !content.includes('<')) {
                    return `<td${attrs} style="word-break: break-all;">${content}</td>`;
                }
                return `<td${attrs}>${content}</td>`;
            });
    } catch (err) {
        return html; // 出错时返回原始HTML
    }
};

/**
 * 格式化AI回复内容
 * @param {string|object} content - 原始回复内容
 * @returns {string} - 格式化后的HTML
 */
export const formatAIResponse = (content) => {
    // 检查并确保输入是字符串
    if (content === null || content === undefined) {
        return '';
    }

    try {
        let contentStr = content;

        // 如果是JSON字符串，尝试解析出代码内容
        if (typeof content === 'string') {
            try {
                // 尝试解析为JSON
                const parsedContent = JSON.parse(content);

                // 如果是代码对象，直接提取代码内容
                if (parsedContent && parsedContent.type === 'code') {
                    const codeContent = parsedContent.text || parsedContent.raw || '';
                    const langTag = parsedContent.lang || 'plaintext';

                    if (codeContent) {
                        // 直接构建代码块，跳过JSON显示
                        contentStr = '```' + langTag + '\n' + codeContent + '\n```';
                    }
                }
            } catch (e) {
                // 不是有效的JSON，保持原样
            }

            // 尝试优化表格格式 - 处理不规范的表格
            if (typeof contentStr === 'string' && contentStr.includes('|')) {
                contentStr = fixTableFormat(contentStr);
            }
        }

        // 如果输入是对象，尝试提取代码内容或转换为JSON字符串
        if (typeof content === 'object') {
            try {
                // 首先检查是否是代码对象
                if (content.type === 'code' && (content.text || content.raw)) {
                    // 提取代码内容和语言
                    let codeContent = content.text || content.raw || '';
                    let langTag = content.lang || 'plaintext';

                    // 如果原始内容中包含```标记，尝试提取代码块内容
                    if (typeof codeContent === 'string' && codeContent.includes('```')) {
                        const codeBlockMatch = codeContent.match(/```(?:\w*\n)?([\s\S]*?)```/);
                        if (codeBlockMatch && codeBlockMatch[1]) {
                            codeContent = codeBlockMatch[1];
                        }

                        // 尝试提取语言标签
                        const langMatch = codeContent.match(/```(\w+)\n/);
                        if (langMatch && langMatch[1] && !content.lang) {
                            langTag = langMatch[1];
                        }
                    }

                    // 构建代码块
                    contentStr = '```' + langTag + '\n' + codeContent + '\n```';
                }
                // 检查是否有其他代码相关属性
                else if (content.code || content.source || content.value) {
                    let codeContent = content.code || content.source || content.value || '';
                    let langTag = content.language || content.lang || 'plaintext';

                    // 构建代码块
                    contentStr = '```' + langTag + '\n' + codeContent + '\n```';
                }
                // 检查是否有消息内容
                else if (content.message || content.content || content.text) {
                    contentStr = content.message || content.content || content.text || '';
                }
                // 如果都不是，则作为JSON处理
                else {
                    contentStr = JSON.stringify(content, null, 2);
                    // 作为代码块处理JSON
                    contentStr = '```json\n' + contentStr + '\n```';
                }
            } catch (e) {
                contentStr = String(content);
            }
        } else if (typeof content !== 'string') {
            contentStr = String(content || '');
        }

        // 预处理
        const processedContent = preProcessText(contentStr);

        // 使用marked解析Markdown
        let html = safeMarked(processedContent);

        // 恢复表格
        html = restoreTablesAfterProcessing(html);

        // 检查是否包含表格
        containsTable(processedContent);

        // 后处理
        html = postProcessHtml(html);

        // 最后一次检查，确保没有[object Object]undefined
        html = cleanHtmlObjectText(html);

        return html;
    } catch (err) {
        // 发生错误时使用简单的HTML转义
        return safeToString(content)
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/\n/g, '<br>');
    }
};

/**
 * 修复表格格式问题
 * @param {string} content - 原始内容
 * @returns {string} - 修正后的内容
 */
const fixTableFormat = (content) => {
    try {
        // 检查是否包含可能的表格
        if (!content || typeof content !== 'string' || !content.includes('|')) {
            return content;
        }

        return content;
    } catch (e) {
        // 处理失败返回原内容
        console.error("表格处理错误:", e);
        return content;
    }
};

/**
 * 检测内容是否包含代码块
 * @param {string} content - 要检查的内容
 * @returns {boolean} - 是否包含代码块
 */
export const containsCodeBlock = (content) => {
    return content && /```[\s\S]*?```/.test(content);
};

/**
 * 检测内容是否包含表格
 * @param {string} content - 要检查的内容
 * @returns {boolean} - 是否包含表格
 */
export const containsTable = (content) => {
    // 检查是否是字符串
    if (!content || typeof content !== 'string') {
        return false;
    }

    // 更宽松的表格模式匹配，只要有表格特征就算
    return content.split('\n').some(line =>
        line.trim().startsWith('|') && line.trim().endsWith('|') && line.indexOf('|', 1) > 1
    );
};